'use strict'; // 启用严格模式

//--------------------------------------------------------------------------
// 获取 DOM 元素 (添加更多检查)
//--------------------------------------------------------------------------
const canvas = document.getElementById('solarSystemCanvas');
if (!canvas) throw new Error("未找到 Canvas 'solarSystemCanvas'");
const ctx = canvas.getContext('2d');
if (!ctx) throw new Error("无法获取 Canvas 2D 上下文");

const timeSpeedDisplay = document.getElementById('timeSpeedDisplay');
const slowDownButton = document.getElementById('slowDownButton');
const speedUpButton = document.getElementById('speedUpButton');
const resetSpeedButton = document.getElementById('resetSpeedButton');
const toggleRunButton = document.getElementById('toggleRunButton');
const toggleOrbitsButton = document.getElementById('toggleOrbitsButton');
const toggleLabelsButton = document.getElementById('toggleLabelsButton');
const toggleTrailsButton = document.getElementById('toggleTrailsButton');
const focusPlanetButton = document.getElementById('focusPlanetButton');
const resetViewButton = document.getElementById('resetViewButton');
const infoPanel = document.getElementById('infoPanel');
const infoName = document.getElementById('infoName');
const infoRadius = document.getElementById('infoRadius');
const infoOrbitRadius = document.getElementById('infoOrbitRadius');
const infoPeriod = document.getElementById('infoPeriod');
const infoTemp = document.getElementById('infoTemp');
const infoGrav = document.getElementById('infoGrav');
const infoMoons = document.getElementById('infoMoons');
const infoFact = document.getElementById('infoFact');
const infoImageContainer = document.querySelector('.info-image-container');
const infoImage = document.getElementById('infoImage');
const selectionHint = document.getElementById('selectionHint');

// 检查所有必要的 DOM 元素是否存在
const requiredElements = { canvas, ctx, timeSpeedDisplay, slowDownButton, speedUpButton, resetSpeedButton, toggleRunButton, toggleOrbitsButton, toggleLabelsButton, toggleTrailsButton, focusPlanetButton, resetViewButton, infoPanel, infoName, infoRadius, infoOrbitRadius, infoPeriod, infoTemp, infoGrav, infoMoons, infoFact, infoImageContainer, infoImage, selectionHint };
let missingElements = [];
for (const key in requiredElements) {
    if (!requiredElements[key]) {
        missingElements.push(key);
    }
}
if (missingElements.length > 0) {
    console.warn(`警告：未能找到以下 DOM 元素: ${missingElements.join(', ')}。某些 UI 功能可能无法工作。`);
}


//--------------------------------------------------------------------------
// 配置常量
//--------------------------------------------------------------------------
const AU = 149.6e6 * 1000;
const INITIAL_VIEW_WIDTH_FRACTION = 0.4;
const NEPTUNE_ORBIT_AU = 30.069;
let SCALE = 1e-12;
const PLANET_SIZE_MULTIPLIER = 5;
const MOON_SIZE_MULTIPLIER = 30;
const SUN_SIZE_MULTIPLIER = 0.1;
const MIN_SUN_PIXEL_RADIUS = 5;
const MIN_PLANET_PIXEL_RADIUS = 2;
const MIN_MOON_PIXEL_RADIUS = 1;
const TIME_SCALE = 1e7;
const MAX_TRAIL_POINTS = 60;
const CLICK_TOLERANCE = 15;

//--------------------------------------------------------------------------
// 模拟状态变量
//--------------------------------------------------------------------------
let canvasWidth = 0; let canvasHeight = 0;
let centerX = 0; let centerY = 0;
let zoomLevel = 1;
let panX = 0; let panY = 0;
let targetPanX = 0; let targetPanY = 0; let targetZoomLevel = 1;
let isFocusing = false; const FOCUS_SPEED = 0.08;
let isDragging = false; let lastMouseX = 0; let lastMouseY = 0;
let lastTime = 0; let isRunning = true;
let animationFrameId = null;

//--------------------------------------------------------------------------
// 控制状态变量
//--------------------------------------------------------------------------
let timeMultiplier = 1.0;
let showOrbits = true; let showLabels = true; let showTrails = false; // showLabels 默认 true
let selectedPlanet = null;

//--------------------------------------------------------------------------
// 天体数据 (确保数据完整)
//--------------------------------------------------------------------------
const sun = { id: "sun", name: "太阳 (Sun)", radius: 696340 * 1000, color: '#FFD700', mass: 1.989e30, isSun: true, info: { radius: "696,340 km", orbitRadius: "N/A", period: "N/A", moons: "N/A", temperature: "核心约1500万°C, 表面约5500°C", gravity: "约 274 m/s² (地球的28倍)", composition: "氢 (~74%), 氦 (~24%), 其他", fact: "太阳是一颗G型主序星，通过核聚变产生光和热，其能量主导着整个太阳系。", imageUrl: "https://placehold.co/280x180/FFD700/000000?text=Sun" } };
const planets = [
    { id: "mercury", name: "水星 (Mercury)", radius: 2439 * 1000, color: '#A9A9A9', orbitRadiusAU: 0.387, periodDays: 88, angle: Math.random() * 2 * Math.PI, moons: [], trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, info: { radius: "2,439 km", orbitRadius: "0.39 AU", period: "88 天", moons: "无", temperature: "白天约430°C, 夜间约-180°C", gravity: "约 3.7 m/s² (地球的0.38倍)", composition: "岩石，富含金属的核心", fact: "水星拥有极稀薄的外逸层大气，其轨道是所有行星中最椭圆的。", imageUrl: "https://placehold.co/280x180/A9A9A9/FFFFFF?text=Mercury" } },
    { id: "venus",   name: "金星 (Venus)",   radius: 6051 * 1000, color: '#E6E6FA', orbitRadiusAU: 0.723, periodDays: 225, angle: Math.random() * 2 * Math.PI, moons: [], trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, info: { radius: "6,051 km", orbitRadius: "0.72 AU", period: "225 天", moons: "无", temperature: "平均约 465°C (失控温室效应)", gravity: "约 8.87 m/s² (地球的0.9倍)", composition: "岩石, 极厚的二氧化碳大气", fact: "金星自转方向与其他大多数行星相反（逆行自转），且自转非常缓慢。", imageUrl: "https://placehold.co/280x180/E6E6FA/000000?text=Venus" } },
    { id: "earth",   name: "地球 (Earth)",   radius: 6371 * 1000, color: '#2090FF', orbitRadiusAU: 1, periodDays: 365.25, angle: Math.random() * 2 * Math.PI, trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, moons: [ { id: "moon", name: "月球 (Moon)", radius: 1737 * 1000, color: '#CCCCCC', orbitRadiusKm: 384400, periodDays: 27.3, angle: Math.random() * 2 * Math.PI, info: { radius: "1,737 km", orbitRadius: "384,400 km (绕地球)", period: "27.3 天", moons: "N/A", temperature: "白天约120°C, 夜间约-170°C", gravity: "约 1.62 m/s² (地球的0.16倍)", composition: "岩石, 无大气层", fact: "月球总是以同一面朝向地球（潮汐锁定），其形成可能源于早期地球与一颗火星大小天体的碰撞。", imageUrl: "https://placehold.co/280x180/CCCCCC/000000?text=Moon" }} ], info: { radius: "6,371 km", orbitRadius: "1 AU (约1.5亿公里)", period: "365.25 天", moons: "1 (月球)", temperature: "平均约 15°C", gravity: "约 9.8 m/s²", composition: "氮氧大气, 液态水, 硅酸盐地壳", fact: "地球是目前已知唯一拥有液态水表面和支持复杂生命的行星。", imageUrl: "https://placehold.co/280x180/2090FF/FFFFFF?text=Earth" } },
    { id: "mars",    name: "火星 (Mars)",    radius: 3389 * 1000, color: '#FF5733', orbitRadiusAU: 1.524, periodDays: 687, angle: Math.random() * 2 * Math.PI, moons: [], trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, info: { radius: "3,389 km", orbitRadius: "1.52 AU", period: "687 天", moons: "2 (微小)", temperature: "平均约 -63°C", gravity: "约 3.71 m/s² (地球的0.38倍)", composition: "稀薄二氧化碳大气, 氧化铁地表", fact: "火星拥有季节变化和极地冰盖，是太阳系中除地球外最可能存在过生命或未来可能支持生命的行星。", imageUrl: "https://placehold.co/280x180/FF5733/FFFFFF?text=Mars" } },
    { id: "jupiter", name: "木星 (Jupiter)", radius: 69911 * 1000, color: '#D2B48C', orbitRadiusAU: 5.203, periodDays: 4333, angle: Math.random() * 2 * Math.PI, moons: [], trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, info: { radius: "69,911 km", orbitRadius: "5.20 AU", period: "11.9 年", moons: "95+", temperature: "云顶约 -145°C", gravity: "约 24.79 m/s² (地球的2.5倍)", composition: "氢 (~90%), 氦 (~10%)", fact: "木星是气态巨行星，其强大的磁场和众多卫星构成了一个微型“太阳系”。", imageUrl: "https://placehold.co/280x180/D2B48C/000000?text=Jupiter" } },
    { id: "saturn",  name: "土星 (Saturn)",  radius: 58232 * 1000, color: '#F4A460', orbitRadiusAU: 9.537, periodDays: 10759, angle: Math.random() * 2 * Math.PI, hasRing: true, moons: [], trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, info: { radius: "58,232 km", orbitRadius: "9.54 AU", period: "29.5 年", moons: "146+", temperature: "云顶约 -178°C", gravity: "约 10.44 m/s² (地球的1.06倍)", composition: "氢, 氦", fact: "土星的密度小于水，如果能找到足够大的浴缸，它会浮起来！其环系由无数冰粒组成。", imageUrl: "https://placehold.co/280x180/F4A460/000000?text=Saturn" } },
    { id: "uranus",  name: "天王星 (Uranus)",radius: 25362 * 1000, color: '#AFEEEE', orbitRadiusAU: 19.191, periodDays: 30687, angle: Math.random() * 2 * Math.PI, moons: [], trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, info: { radius: "25,362 km", orbitRadius: "19.19 AU", period: "84 年", moons: "27+", temperature: "云顶约 -216°C", gravity: "约 8.69 m/s² (地球的0.89倍)", composition: "氢, 氦, 甲烷冰", fact: "天王星因大气中的甲烷吸收红光而呈现淡蓝色，其极端倾斜的自转轴导致极端的季节变化。", imageUrl: "https://placehold.co/280x180/AFEEEE/000000?text=Uranus" } },
    { id: "neptune", name: "海王星 (Neptune)",radius: 24622 * 1000, color: '#3F51B5', orbitRadiusAU: 30.069, periodDays: 60190, angle: Math.random() * 2 * Math.PI, moons: [], trailPoints: [], maxTrailPoints: MAX_TRAIL_POINTS, info: { radius: "24,622 km", orbitRadius: "30.07 AU", period: "164.8 年", moons: "14+", temperature: "云顶约 -214°C", gravity: "约 11.15 m/s² (地球的1.14倍)", composition: "氢, 氦, 甲烷冰", fact: "海王星是依据数学预测发现的第一颗行星，拥有动态的大气活动，包括曾观测到的大黑斑。", imageUrl: "https://placehold.co/280x180/3F51B5/FFFFFF?text=Neptune" } }
];

//--------------------------------------------------------------------------
// 初始化函数
//--------------------------------------------------------------------------
function initializeSimulation() {
    console.log(">>> 初始化模拟开始...");
    try {
        resizeCanvas();
        if (canvasWidth <= 0 || canvasHeight <= 0 || !SCALE || SCALE <= 0) throw new Error(`画布尺寸或 SCALE 无效`);
        console.log(`  [OK] 画布尺寸和 SCALE: ${canvasWidth}x${canvasHeight}, Scale=${SCALE.toExponential(2)}`);

        console.log("  计算天体基础属性...");
        sun.baseDisplayRadius = sun.radius * SCALE * SUN_SIZE_MULTIPLIER;
        if (isNaN(sun.baseDisplayRadius)) throw new Error("太阳 baseDisplayRadius 计算失败");

        planets.forEach((p, index) => {
            p.angularSpeed = (2 * Math.PI) / (p.periodDays * 24 * 3600) * TIME_SCALE;
            p.baseDisplayRadius = p.radius * SCALE * PLANET_SIZE_MULTIPLIER;
            p.baseOrbitRadius = p.orbitRadiusAU * AU * SCALE;
            p.trailPoints = [];
            if (isNaN(p.angularSpeed) || isNaN(p.baseDisplayRadius) || isNaN(p.baseOrbitRadius) || p.baseOrbitRadius < 0) throw new Error(`行星 ${index} (${p.name}) 属性计算失败`);
            if (p.moons && p.moons.length > 0) {
                p.moons.forEach((m, mIndex) => {
                    if (!m || !m.periodDays || !m.orbitRadiusKm || !m.radius) throw new Error(`月球 ${mIndex} 数据不完整`);
                    m.angularSpeed = (2 * Math.PI) / (m.periodDays * 24 * 3600) * TIME_SCALE;
                    m.baseOrbitRadius = m.orbitRadiusKm * 1000 * SCALE * 10;
                    m.baseDisplayRadius = m.radius * SCALE * MOON_SIZE_MULTIPLIER;
                    if (isNaN(m.angularSpeed) || isNaN(m.baseOrbitRadius) || isNaN(m.baseDisplayRadius) || m.baseOrbitRadius <= 0) throw new Error(`月球 ${mIndex} (${m.name}) 属性计算失败`);
                });
            }
        });
        console.log("  [OK] 天体属性计算完成");

        console.log("  计算初始缩放...");
        const neptune = planets.find(p => p.id === "neptune");
        if (neptune && neptune.baseOrbitRadius > 0) {
            targetZoomLevel = zoomLevel = (canvasWidth * INITIAL_VIEW_WIDTH_FRACTION) / neptune.baseOrbitRadius;
            targetZoomLevel = zoomLevel = Math.max(0.0001, zoomLevel);
            if (isNaN(zoomLevel)) throw new Error("计算初始 zoomLevel 失败");
        } else {
            console.warn("  未能使用海王星计算缩放，使用备用值 0.05"); targetZoomLevel = zoomLevel = 0.05;
        }
        console.log(`  [OK] 初始 Zoom: ${zoomLevel.toFixed(4)}`);

        targetPanX = panX = 0; targetPanY = panY = 0; lastTime = 0;
        console.log("  更新 UI 状态...");
        updateButtonStates(); updateSpeedDisplay(); updateInfoPanel(null);
        console.log("  [OK] UI 更新完成");

        console.log(">>> 初始化成功，启动动画循环...");
        if (animationFrameId) cancelAnimationFrame(animationFrameId);
        animationFrameId = requestAnimationFrame(animate);
        console.log("动画循环已请求。 ID:", animationFrameId);

    } catch (error) {
        console.error("!!! 初始化过程中发生严重错误:", error);
        alert(`初始化模拟失败: ${error.message}\n请检查浏览器控制台。`);
        if (animationFrameId) cancelAnimationFrame(animationFrameId);
        document.body.innerHTML = `<div style="color: red; padding: 20px;">抱歉，模拟加载失败。错误: ${error.message}</div>`;
    }
}

//--------------------------------------------------------------------------
// 绘图函数
//--------------------------------------------------------------------------
function drawStarfield(ctx, width, height) {
    ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
    if (!window.stars || window.stars.length === 0 || window.starCanvasWidth !== width) {
        window.stars = [];
        for (let i = 0; i < 150; i++) { window.stars.push({ x: Math.random() * width, y: Math.random() * height, radius: Math.random() * 1.0 }); }
        window.starCanvasWidth = width;
    }
     window.stars.forEach(star => {
        const parallaxFactor = 0.02;
        const screenX = (star.x - centerX + panX * parallaxFactor); const screenY = (star.y - centerY + panY * parallaxFactor);
        const x = ((screenX % width) + width) % width; const y = ((screenY % height) + height) % height;
        ctx.beginPath(); ctx.arc(x, y, star.radius, 0, Math.PI * 2); ctx.fill();
    });
}

function drawSun(ctx) {
    const drawnRadius = Math.max(MIN_SUN_PIXEL_RADIUS, sun.baseDisplayRadius * zoomLevel);
    if (isNaN(drawnRadius) || drawnRadius <= 0) { console.warn("太阳绘制半径无效"); return; }
    ctx.save();
    ctx.shadowBlur = Math.min(35, drawnRadius * 1.8); ctx.shadowColor = sun.color;
    ctx.beginPath(); ctx.arc(0, 0, drawnRadius, 0, Math.PI * 2);
    ctx.fillStyle = sun.color; ctx.fill();
    ctx.restore();
    sun.screenX = centerX + panX; sun.screenY = centerY + panY;
    sun.drawnRadius = drawnRadius; sun.currentX = 0; sun.currentY = 0;
}

function drawPlanet(ctx, planet) {
    const drawnOrbitRadius = planet.baseOrbitRadius * zoomLevel;
    const x = drawnOrbitRadius * Math.cos(planet.angle);
    const y = drawnOrbitRadius * Math.sin(planet.angle);
    const drawnRadius = Math.max(MIN_PLANET_PIXEL_RADIUS, planet.baseDisplayRadius * zoomLevel);
    if (isNaN(x) || isNaN(y) || isNaN(drawnRadius) || drawnRadius <= 0 || isNaN(drawnOrbitRadius)) return;

    planet.currentX = x; planet.currentY = y;
    planet.screenX = centerX + panX + x; planet.screenY = centerY + panY + y;
    planet.drawnRadius = drawnRadius;

    // Draw Trail
    if (showTrails && planet.trailPoints.length > 1) {
        ctx.save();
        ctx.lineWidth = Math.max(0.5, 1.5 * zoomLevel);
        ctx.beginPath();
        ctx.moveTo(planet.trailPoints[0].x * zoomLevel, planet.trailPoints[0].y * zoomLevel);
        for (let i = 1; i < planet.trailPoints.length; i++) {
             const point = planet.trailPoints[i];
             if (isNaN(point.x) || isNaN(point.y)) continue;
             ctx.lineTo(point.x * zoomLevel, point.y * zoomLevel);
        }
        ctx.strokeStyle = `rgba(200, 220, 255, 0.4)`;
        ctx.stroke();
        ctx.restore();
    }

    // Draw Orbit Path
    if (showOrbits && drawnOrbitRadius > 2) {
        ctx.beginPath(); ctx.arc(0, 0, drawnOrbitRadius, 0, Math.PI * 2);
        ctx.strokeStyle = 'rgba(180, 200, 255, 0.15)'; ctx.lineWidth = 1; ctx.stroke();
    }

    // Draw Planet
    ctx.beginPath(); ctx.arc(x, y, drawnRadius, 0, Math.PI * 2);
    ctx.fillStyle = planet.color;
    ctx.save(); if (drawnRadius > 1.5) { ctx.shadowColor = 'rgba(0,0,0,0.5)'; ctx.shadowBlur = Math.max(1, drawnRadius * 0.5); ctx.shadowOffsetX = Math.max(1, drawnRadius * 0.2); ctx.shadowOffsetY = Math.max(1, drawnRadius * 0.2); } ctx.fill(); ctx.restore();

    // Rings and Moons
    if (planet.hasRing) drawSaturnRing(ctx, x, y, drawnRadius);
    if (planet.moons && planet.moons.length > 0) {
        planet.moons.forEach(moon => { try { drawMoon(ctx, moon, x, y); } catch (moonError) { console.error(`绘制月球 ${moon.name} 出错:`, moonError); } });
    }

    // **1. 强制绘制地球标签，忽略所有条件 (用于测试绘图本身)**
    // if (planet.id === 'earth') { // 只针对地球测试
    //     const forceLabelX = x + drawnRadius + 5;
    //     const forceLabelY = y + drawnRadius * 0.5 + 3;

    //     // 检查强制坐标
    //     if (!isNaN(forceLabelX) && !isNaN(forceLabelY)) {
    //         ctx.fillStyle = 'red'; // 使用醒目的颜色
    //         ctx.font = '12px Arial'; // 使用最简单的字体
    //         ctx.textAlign = 'left';
    //         const labelText = `地球 TEST (${showLabels})`; // 显示 showLabels 状态

    //         try {
    //             ctx.fillText(labelText, forceLabelX, forceLabelY);
    //             if (frameCount < 10) console.log(`  [强制绘制] 标签 ${labelText} at (${forceLabelX.toFixed(0)}, ${forceLabelY.toFixed(0)})`);
    //         } catch (fillTextError) {
    //             console.error(`  [强制绘制] 绘制标签 ${labelText} 时出错:`, fillTextError);
    //         }
    //     } else if (frameCount < 10){
    //         console.warn(`  [强制绘制] 地球标签坐标无效: labelX=${forceLabelX}, labelY=${forceLabelY}`);
    //     }
    // }

    // --- 标签绘制逻辑 (最终版本，移除了强制绘制) ---
    const labelZoomThreshold = 0.001; // 设置一个极小值
    const labelRadiusThreshold = 0.1;  // 设置一个极小值

    // 调试日志 (可注释掉)
    // const shouldLogLabelCheck = frameCount % 60 === 0 && (planet.id === 'earth' || planet.id === 'mercury'); // 每秒检查一次特定行星
    // if (shouldLogLabelCheck) {
    //     console.log(`标签检查 ${planet.name}: showLabels=${showLabels}, zoom=${zoomLevel.toFixed(3)}>${labelZoomThreshold}, drawnR=${drawnRadius.toFixed(1)}>${labelRadiusThreshold}`);
    // }

    if (showLabels && zoomLevel > labelZoomThreshold && drawnRadius > labelRadiusThreshold) {
        // **恢复使用 Exo 2 字体，如果加载成功的话，否则 Arial 作为备用**
        ctx.font = `10px "Exo 2", Arial, sans-serif`;
        ctx.fillStyle = 'rgba(200, 220, 255, 0.9)'; // 稍微提高透明度
        ctx.textAlign = 'left';
        // 添加一点背景，让文字更清晰 (可选)
        ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
        ctx.fillRect(x + drawnRadius + 2, y + drawnRadius * 0.5 - 8, ctx.measureText(planet.name.split(' ')[0]).width + 4, 12);
        ctx.fillStyle = 'rgba(200, 220, 255, 0.9)'; // 恢复文字颜色

        const labelX = x + drawnRadius + 5; // 稍微增加间距
        const labelY = y + drawnRadius * 0.5 + 3; // 垂直居中调整

        if (!isNaN(labelX) && !isNaN(labelY)) {
            const labelText = planet.name.split(' ')[0];
            try {
                ctx.fillText(labelText, labelX, labelY);
                // if (shouldLogLabelCheck) { console.log(`  绘制标签 ${labelText} at (${labelX.toFixed(0)}, ${labelY.toFixed(0)})`); }
            } catch (fillTextError) { console.error(`绘制标签 ${labelText} 时出错:`, fillTextError); }
        }
    }
    // --- 标签绘制逻辑结束 ---
}

function drawSaturnRing(ctx, planetX, planetY, planetDrawnRadius) {
    const ringOuterRadius = planetDrawnRadius * 2.2;
    const ringInnerRadius = planetDrawnRadius * 1.5;
    if (ringOuterRadius < 1.5 || isNaN(ringOuterRadius) || isNaN(ringInnerRadius)) return;
    ctx.save(); ctx.translate(planetX, planetY); ctx.rotate(0.2); ctx.scale(1, 0.4);
    ctx.beginPath();
    ctx.arc(0, 0, ringOuterRadius, 0, Math.PI * 2, false);
    if (ringInnerRadius > 0.5) ctx.arc(0, 0, ringInnerRadius, 0, Math.PI * 2, true);
    ctx.fillStyle = 'rgba(180, 160, 130, 0.6)'; ctx.fill();
    ctx.restore();
}

function drawMoon(ctx, moon, planetX, planetY) {
    const drawnMoonOrbitRadius = moon.baseOrbitRadius * zoomLevel;
    const moonOffsetX = drawnMoonOrbitRadius * Math.cos(moon.angle);
    const moonOffsetY = drawnMoonOrbitRadius * Math.sin(moon.angle);
    const moonX = planetX + moonOffsetX;
    const moonY = planetY + moonOffsetY;
    const drawnMoonRadius = Math.max(MIN_MOON_PIXEL_RADIUS, moon.baseDisplayRadius * zoomLevel);
    if (isNaN(moonX) || isNaN(moonY) || isNaN(drawnMoonRadius) || drawnMoonRadius <= 0 || isNaN(drawnMoonOrbitRadius)) return;

    moon.currentX = moonX; moon.currentY = moonY;
    moon.screenX = centerX + panX + moonX; moon.screenY = centerY + panY + moonY;
    moon.drawnRadius = drawnMoonRadius;

    if (showOrbits && drawnMoonOrbitRadius > 1.5) {
        ctx.beginPath(); ctx.arc(planetX, planetY, drawnMoonOrbitRadius, 0, Math.PI*2);
        ctx.strokeStyle = 'rgba(180, 180, 200, 0.1)'; ctx.lineWidth = 0.5; ctx.stroke();
    }
    ctx.beginPath(); ctx.arc(moonX, moonY, drawnMoonRadius, 0, Math.PI * 2);
    ctx.fillStyle = moon.color; ctx.fill();
}

//--------------------------------------------------------------------------
// 更新函数
//--------------------------------------------------------------------------
function updatePositions(deltaTime) {
    if (!isRunning || isNaN(deltaTime) || deltaTime <= 0 || deltaTime > 0.5) return;
    const effectiveDeltaTime = deltaTime * timeMultiplier;
    if (isNaN(effectiveDeltaTime)) { console.warn("Effective deltaTime is NaN"); return; }

    planets.forEach(p => {
        const deltaAngle = p.angularSpeed * effectiveDeltaTime;
        if(isNaN(deltaAngle)) { console.warn(`NaN deltaAngle for ${p.name}`); return; }
        p.angle += deltaAngle; p.angle %= (2 * Math.PI);

        if (showTrails || p.trailPoints.length < p.maxTrailPoints) {
            const currentOrbitRadius = p.baseOrbitRadius;
            if (isNaN(currentOrbitRadius) || currentOrbitRadius < 0) return;
            const currentX = currentOrbitRadius * Math.cos(p.angle);
            const currentY = currentOrbitRadius * Math.sin(p.angle);
            if (isNaN(currentX) || isNaN(currentY)) return;
            p.trailPoints.push({ x: currentX, y: currentY });
            if (p.trailPoints.length > p.maxTrailPoints) p.trailPoints.shift();
        }

        if (p.moons && p.moons.length > 0) {
            p.moons.forEach(m => {
                const deltaMoonAngle = m.angularSpeed * effectiveDeltaTime;
                if(isNaN(deltaMoonAngle)) return;
                m.angle += deltaMoonAngle; m.angle %= (2 * Math.PI);
            });
        }
    });
}

//--------------------------------------------------------------------------
// 动画循环
//--------------------------------------------------------------------------
let frameCount = 0;
function animate(currentTime) {
    frameCount++;

    // --- DeltaTime Calculation ---
    if (!lastTime) lastTime = currentTime;
    let deltaTime = (currentTime - lastTime) / 1000;
    lastTime = currentTime;
    deltaTime = Math.min(deltaTime, 0.1); // Clamp

    // --- Smooth Pan/Zoom ---
    if (isFocusing) {
        const dx = targetPanX - panX; const dy = targetPanY - panY; const dz = targetZoomLevel - zoomLevel;
        if (Math.abs(dx) < 0.1 && Math.abs(dy) < 0.1 && Math.abs(dz) < 0.0001) {
            isFocusing = false; panX = targetPanX; panY = targetPanY; zoomLevel = targetZoomLevel;
        } else { panX += dx * FOCUS_SPEED; panY += dy * FOCUS_SPEED; zoomLevel += dz * FOCUS_SPEED; }
    }

    // --- 检查画布有效性 ---
    if (!ctx || canvasWidth <= 0 || canvasHeight <= 0) {
        console.error(`停止动画：无效的上下文或画布尺寸 (${canvasWidth}x${canvasHeight}) in frame ${frameCount}`);
        if (animationFrameId) { cancelAnimationFrame(animationFrameId); animationFrameId = null; }
        return;
    }

    // --- 清除画布 & 背景 ---
    try {
        ctx.clearRect(0, 0, canvasWidth, canvasHeight);
        ctx.fillStyle = "#000010";
        ctx.fillRect(0, 0, canvasWidth, canvasHeight);
    } catch (clearError) { console.error(`清除画布出错 in frame ${frameCount}:`, clearError); if (animationFrameId) { cancelAnimationFrame(animationFrameId); animationFrameId = null; } return; }

    // --- 更新位置 ---
    try { updatePositions(deltaTime); } catch(updateError){ console.error(`更新位置出错 in frame ${frameCount}:`, updateError); }

    // --- 绘图 ---
    try { drawStarfield(ctx, canvasWidth, canvasHeight); } catch(starError) { console.error(`绘制星星出错 in frame ${frameCount}:`, starError); }

    ctx.save(); // 2. 天体
    ctx.translate(centerX + panX, centerY + panY);
    try {
        drawSun(ctx);
        if (planets && planets.length > 0) {
            planets.forEach(planet => { drawPlanet(ctx, planet); });
        } else if (frameCount === 1) { console.error("  无法绘制行星，planets 数组为空或无效"); }
    } catch (drawingError) { console.error(`!!! 绘图出错 in frame ${frameCount}:`, drawingError); }
    finally { ctx.restore(); }

    // 3. 调试信息 (移除了固定坐标测试点)
     try {
        ctx.fillStyle = "yellow"; ctx.font = "12px Arial"; ctx.textAlign = "left";
        ctx.fillText(`Frame: ${frameCount}`, 10, 20);
        ctx.fillText(`Zoom: ${zoomLevel.toFixed(4)}`, 10, 35);
        ctx.fillText(`Pan: (${panX.toFixed(0)}, ${panY.toFixed(0)})`, 10, 50);
        ctx.fillText(`Running: ${isRunning}`, 10, 65);
        ctx.fillText(`Labels: ${showLabels}`, 10, 80); // 持续显示标签状态
     } catch (debugTextError) { console.error("绘制调试文本出错:", debugTextError); }

    // --- 请求下一帧 ---
    animationFrameId = requestAnimationFrame(animate);
}

//--------------------------------------------------------------------------
// 事件监听器 & 处理器
//--------------------------------------------------------------------------
function resizeCanvas() {
    console.log("正在调整画布尺寸...");
    canvasWidth = Math.max(300, window.innerWidth * 0.9);
    canvasHeight = Math.max(200, window.innerHeight * 0.75);
    if (canvasWidth <= 0 || canvasHeight <= 0) {
        console.error("调整尺寸时出错：无效的画布尺寸", canvasWidth, canvasHeight);
        SCALE = 1e-12; return;
    }
    canvas.width = canvasWidth; canvas.height = canvasHeight;
    centerX = canvasWidth / 2; centerY = canvasHeight / 2;

    if (AU > 0 && NEPTUNE_ORBIT_AU > 0 && canvasWidth > 0) {
        SCALE = (canvasWidth * INITIAL_VIEW_WIDTH_FRACTION) / (NEPTUNE_ORBIT_AU * AU);
        if (isNaN(SCALE) || SCALE <= 0) { SCALE = 1e-12; console.warn("SCALE 计算无效，使用备用值。"); }
    } else { SCALE = 1e-12; console.error("无法计算 SCALE，常量或宽度无效。"); }

    window.stars = [];

    if (sun && planets && planets.length > 0 && SCALE > 0) {
        try {
            sun.baseDisplayRadius = sun.radius * SCALE * SUN_SIZE_MULTIPLIER;
            if (isNaN(sun.baseDisplayRadius)) throw new Error("Sun baseDisplayRadius NaN");
            planets.forEach(p => {
                p.baseDisplayRadius = p.radius * SCALE * PLANET_SIZE_MULTIPLIER;
                p.baseOrbitRadius = p.orbitRadiusAU * AU * SCALE;
                if (isNaN(p.baseDisplayRadius) || isNaN(p.baseOrbitRadius)) throw new Error(`${p.name} radius NaN`);
                if (p.moons && p.moons.length > 0) {
                    p.moons.forEach(m => {
                        m.baseOrbitRadius = m.orbitRadiusKm * 1000 * SCALE * 10;
                        m.baseDisplayRadius = m.radius * SCALE * MOON_SIZE_MULTIPLIER;
                        if (isNaN(m.baseOrbitRadius) || isNaN(m.baseDisplayRadius)) throw new Error(`${m.name} radius NaN`);
                    });
                }
            });
            console.log(`调整尺寸完成。Scale:${SCALE.toExponential(2)}, Canvas:${canvasWidth}x${canvasHeight}`);
        } catch (error) {
            console.error("调整尺寸时重新计算半径出错:", error);
            SCALE = 1e-12; if (animationFrameId) cancelAnimationFrame(animationFrameId); animationFrameId = null;
        }
        if(isFocusing) { isFocusing = false; }
    } else { console.error("调整尺寸后未重新计算半径。"); }
}
window.addEventListener('resize', resizeCanvas);

canvas.addEventListener('wheel', (event) => {
    event.preventDefault(); isFocusing = false;
    const zoomIntensity = 0.1; const direction = event.deltaY < 0 ? 1 : -1;
    const zoomFactor = 1 + direction * zoomIntensity;
    const rect = canvas.getBoundingClientRect();
    const mouseX = event.clientX - rect.left; const mouseY = event.clientY - rect.top;
    const worldX_before = (mouseX - (centerX + panX)) / zoomLevel;
    const worldY_before = (mouseY - (centerY + panY)) / zoomLevel;
    let newZoomLevel = zoomLevel * zoomFactor;
    newZoomLevel = Math.max(0.0001, Math.min(newZoomLevel, 100));
    zoomLevel = newZoomLevel; targetZoomLevel = zoomLevel;
    panX = mouseX - centerX - worldX_before * zoomLevel;
    panY = mouseY - centerY - worldY_before * zoomLevel;
    targetPanX = panX; targetPanY = panY;
});

canvas.addEventListener('mousedown', (event) => {
    isDragging = true; isFocusing = false;
    lastMouseX = event.clientX; lastMouseY = event.clientY;
    canvas.style.cursor = 'grabbing';
});

canvas.addEventListener('mousemove', (event) => {
    if (isDragging) {
        const dx = event.clientX - lastMouseX; const dy = event.clientY - lastMouseY;
        panX += dx; panY += dy; targetPanX = panX; targetPanY = panY;
        lastMouseX = event.clientX; lastMouseY = event.clientY;
    }
});

canvas.addEventListener('mouseup', (event) => {
    if (isDragging) {
        isDragging = false;
        canvas.style.cursor = 'grab';
    }
});

canvas.addEventListener('mouseout', (event) => {
    if (isDragging && (!event.relatedTarget || event.relatedTarget === document.body || !canvas.contains(event.relatedTarget))) {
        isDragging = false;
        canvas.style.cursor = 'grab';
    }
});

canvas.addEventListener('click', (event) => {
     if (!isDragging) {
        const rect = canvas.getBoundingClientRect();
        const mouseX = event.clientX - rect.left;
        const mouseY = event.clientY - rect.top;
        selectBodyAt(mouseX, mouseY);
    }
});

// --- Button Actions ---
if (toggleRunButton) toggleRunButton.addEventListener('click', () => {
    isRunning = !isRunning; if (isRunning) lastTime = 0; console.log(isRunning ? "Resumed" : "Paused"); updateButtonStates();
});
if (slowDownButton) slowDownButton.addEventListener('click', () => { timeMultiplier /= 1.5; timeMultiplier = Math.max(0.01, timeMultiplier); updateSpeedDisplay(); });
if (speedUpButton) speedUpButton.addEventListener('click', () => { timeMultiplier *= 1.5; timeMultiplier = Math.min(200, timeMultiplier); updateSpeedDisplay(); });
if (resetSpeedButton) resetSpeedButton.addEventListener('click', () => { timeMultiplier = 1.0; updateSpeedDisplay(); });
if (toggleOrbitsButton) toggleOrbitsButton.addEventListener('click', () => { showOrbits = !showOrbits; updateButtonStates(); });
if (toggleLabelsButton) toggleLabelsButton.addEventListener('click', () => {
    showLabels = !showLabels;
    console.log(`标签按钮点击: showLabels 现在是 ${showLabels}`);
    updateButtonStates();
});
if (toggleTrailsButton) toggleTrailsButton.addEventListener('click', () => { showTrails = !showTrails; updateButtonStates(); });
if (resetViewButton) resetViewButton.addEventListener('click', () => {
    console.log("Reset View Clicked"); isFocusing = true; targetPanX = 0; targetPanY = 0;
    try {
        const neptune = planets.find(p => p.id === "neptune");
        if (neptune && neptune.baseOrbitRadius > 0 && canvasWidth > 0) {
            targetZoomLevel = (canvasWidth * INITIAL_VIEW_WIDTH_FRACTION) / neptune.baseOrbitRadius;
            targetZoomLevel = Math.max(0.0001, targetZoomLevel);
            if (isNaN(targetZoomLevel)) throw new Error("计算全景 zoomLevel 失败");
            console.log(`Reset View - Target Zoom calculated: ${targetZoomLevel.toFixed(4)}`);
        } else { throw new Error("无法计算全景缩放"); }
    } catch (error) { console.error("重置视图计算缩放时出错:", error); targetZoomLevel = 0.05; }
});
if (focusPlanetButton) focusPlanetButton.addEventListener('click', () => {
    if (selectedPlanet) {
        if (isNaN(selectedPlanet.currentX) || isNaN(selectedPlanet.currentY)) { console.error(`无法聚焦 ${selectedPlanet.name}: 无效的 currentX/Y`); return; }
        isFocusing = true;
        targetPanX = -selectedPlanet.currentX; targetPanY = -selectedPlanet.currentY;
        targetZoomLevel = zoomLevel; // Keep current zoom
        console.log(`Focusing on ${selectedPlanet.name}. Target Pan: (${targetPanX.toFixed(1)}, ${targetPanY.toFixed(1)})`);
    } else { if (alert) alert("请先点击选择一个天体！"); } // Check if alert exists before calling
});

//--------------------------------------------------------------------------
// UI 更新函数
//--------------------------------------------------------------------------
function updateSpeedDisplay() { if(timeSpeedDisplay) timeSpeedDisplay.textContent = timeMultiplier.toFixed(1); }

function updateButtonStates() {
    if (toggleOrbitsButton) toggleOrbitsButton.classList.toggle('active', showOrbits);
    if (toggleLabelsButton) toggleLabelsButton.classList.toggle('active', showLabels);
    if (toggleTrailsButton) toggleTrailsButton.classList.toggle('active', showTrails);
    if (toggleRunButton) {
        toggleRunButton.classList.toggle('active', isRunning);
        const icon = toggleRunButton.querySelector('i');
        if (icon) {
            if (isRunning) { icon.classList.remove('fa-play'); icon.classList.add('fa-pause'); toggleRunButton.title = "暂停模拟"; }
            else { icon.classList.remove('fa-pause'); icon.classList.add('fa-play'); toggleRunButton.title = "开始模拟"; }
        }
    }
}

function updateInfoPanel(body) {
    if(!infoPanel) return;
    if (body && body.info) {
        // console.log(`更新信息面板，显示: ${body.name}`);
        if(infoName) infoName.textContent = `名称: ${body.name || '--'}`;
        if(infoRadius) infoRadius.textContent = `半径: ${body.info.radius || '--'}`;
        if(infoOrbitRadius) infoOrbitRadius.textContent = `轨道半径: ${body.info.orbitRadius || '--'}`;
        if(infoPeriod) infoPeriod.textContent = `公转周期: ${body.info.period || '--'}`;
        if(infoTemp) infoTemp.textContent = `表面温度: ${body.info.temperature || '--'}`;
        if(infoGrav) infoGrav.textContent = `表面重力: ${body.info.gravity || '--'}`;
        if(infoMoons) infoMoons.textContent = `主要卫星: ${body.info.moons || '--'}`;
        if(infoFact) infoFact.textContent = `简介: ${body.info.fact || '--'}`;
        if (infoImage && infoImageContainer) {
            if (body.info.imageUrl) {
                infoImage.style.display = 'none'; infoImageContainer.style.display = 'flex';
                infoImage.src = body.info.imageUrl; infoImage.alt = `${body.name} 图像`;
                infoImage.onload = () => { infoImage.style.display = 'block'; };
                infoImage.onerror = () => { console.error(`图片 ${body.name} 加载失败: ${infoImage.src}`); infoImage.style.display = 'none'; infoImageContainer.style.display = 'none'; };
            } else { infoImage.src = ""; infoImage.style.display = 'none'; infoImageContainer.style.display = 'none'; }
        }
        if(selectionHint) selectionHint.style.display = 'none';
    } else {
        // console.log("清空信息面板");
        if(infoName) infoName.textContent = `名称: --`; if(infoRadius) infoRadius.textContent = `半径: --`;
        if(infoOrbitRadius) infoOrbitRadius.textContent = `轨道半径: --`; if(infoPeriod) infoPeriod.textContent = `公转周期: --`;
        if(infoTemp) infoTemp.textContent = `表面温度: --`; if(infoGrav) infoGrav.textContent = `表面重力: --`;
        if(infoMoons) infoMoons.textContent = `主要卫星: --`; if(infoFact) infoFact.textContent = `简介: --`;
        if (infoImage) { infoImage.src = ""; infoImage.style.display = 'none'; }
        if (infoImageContainer) infoImageContainer.style.display = 'none';
        if(selectionHint) selectionHint.style.display = 'block';
    }
}


//--------------------------------------------------------------------------
// 辅助函数
//--------------------------------------------------------------------------
function selectBodyAt(mouseX, mouseY) {
    let closestBody = null; let minVisualDistSq = Infinity;
    const clickRadiusSafetyMargin = 1.5;

    const checkBody = (body) => {
        if (!body || body.screenX === undefined || isNaN(body.screenX) || isNaN(body.screenY) || isNaN(body.drawnRadius) || body.drawnRadius < 0) return;
        const dx = mouseX - body.screenX; const dy = mouseY - body.screenY;
        const distSq = dx * dx + dy * dy;
        const effectiveClickRadius = Math.max(body.drawnRadius * clickRadiusSafetyMargin, CLICK_TOLERANCE);
        const effectiveClickRadiusSq = effectiveClickRadius * effectiveClickRadius;

        if (distSq < effectiveClickRadiusSq) {
            if (distSq < minVisualDistSq) { closestBody = body; minVisualDistSq = distSq; }
        }
    };
    checkBody(sun);
    if (planets && planets.length > 0) {
        planets.forEach(planet => {
            checkBody(planet);
            if (planet.moons && planet.moons.length > 0) { planet.moons.forEach(checkBody); }
        });
    }
    selectedPlanet = closestBody;
    if (selectedPlanet) console.log("选中:", selectedPlanet.name); // else console.log("点击空白");
    updateInfoPanel(selectedPlanet); // 在这里调用更新
}

//--------------------------------------------------------------------------
// 启动模拟
//--------------------------------------------------------------------------
document.addEventListener('DOMContentLoaded', () => {
    console.log("DOM 已加载，尝试启动初始化...");
    if (!canvas || !ctx) { console.error("无法启动模拟：Canvas 或上下文无效。"); document.body.innerHTML = `<div style="color: red;">加载失败：缺少 Canvas。</div>`; return; }
    try {
        initializeSimulation(); // 启动入口
    } catch (error) { console.error("顶层初始化错误:", error); /* Error handling inside init */ }
});